//
// (C) Copyright 2009 Irantha Suwandarathna (irantha@gmail.com)
// All rights reserved.
//


/* Copyright (c) 2001-2008, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use _in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions _in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer _in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using EffiProzDB.Lib;
using EffiProzDB.RowIO;



namespace EffiProzDB
{

    // fredt@users 20021205 - path 1.7.2 - enhancements
    // fredt@users 20021215 - doc 1.7.2 - javadoc comments

    /**
     * Implementation of rows for tables with memory resident indexes and
     * disk-based data, such as TEXT tables.
     *
     * @version 1.7.2
     */
    public class CachedDataRow : CachedRow
    {

        /**
         *  Constructor for new rows.
         */
        public CachedDataRow(Table t, Object[] o)
            : base(t, o)
        {



            hasDataChanged = true;
        }

        /**
         *  Constructor when read from the disk into the Cache. The link with
         *  the Nodes is made separetly.
         */
        public CachedDataRow(Table t, RowInputInterface _in)
        {

            tTable = t;
            iPos = _in.getPos();
            storageSize = _in.getSize();
            oData = _in.readData(tTable.getColumnTypes());
            hasDataChanged = false;
        }

        /**
         *  As the indexes are in-memory, this passes the existing primary node
         *  for the construction of the new Row
         */
        public override Row getUpdatedRow()
        {
            return tTable.getRow(iPos, nPrimaryNode);
        }

        /**
         *  Used when data is read from the disk into the Cache the first time.
         *  New Nodes are created which are then indexed.
         */
        public override void setNewNodes()
        {

            int index = tTable.getIndexCount();

            nPrimaryNode = Node.newNode(this, 0, tTable);

            Node n = nPrimaryNode;

            for (int i = 1; i < index; i++)
            {
                n.nNext = Node.newNode(this, i, tTable);
                n = n.nNext;
            }
        }

        /**
         *  Used when data is re-read from the disk into the Cache. The Row is
         *  already indexed so it is linked with the Node _in the primary index.
         *  the Nodes is made separetly.
         */
        void setPrimaryNode(Node primary)
        {
            nPrimaryNode = primary;
        }

        /**
         * returned size does not include the row size written at the beginning
         */
        public override int getRealSize(RowOutputInterface _out)
        {
            return _out.getSize(this);
        }

        /**
         *  Writes the data to disk. Unlike CachedRow, hasChanged is never set
         *  to true when changes are made to the Nodes. (Nodes are in-memory).
         *  The only time this is used is when a new Row is added to the Caches.
         */
        public override void write(RowOutputInterface _out)
        {

            _out.writeSize(storageSize);
            _out.writeData(oData, tTable);
            _out.writeEnd();

            hasDataChanged = false;
        }

        public override bool hasChanged()
        {
            return hasDataChanged;
        }

        /**
         * Sets the file position for the row and registers the row with
         * the table.
         *
         * @param pos position _in data file
         */
        public override void setPos(int pos)
        {

            iPos = pos;

            Node n = nPrimaryNode;

            while (n != null)
            {
                ((PointerNode)n).iData = iPos;
                n = n.nNext;
            }
        }

        /**
         * With the current implementation of TEXT table updates and inserts,
         * the lifetime scope of this method:until redefinition of table
         * data source or shutdown.
         *
         * @param obj the reference object with which to compare.
         * @return <code>true</code> if this object is the same as the obj argument;
         *   <code>false</code> otherwise.
         */
        public override bool Equals(Object obj)
        {

            if (obj == this)
            {
                return true;
            }

            if (obj is CachedDataRow)
            {
                return ((CachedDataRow)obj).iPos == iPos
                       && ((CachedDataRow)obj).tTable == tTable;
            }

            return false;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}
